using System.IO;
using System.Security.Cryptography;

namespace GSN
{
    static class CryptUtils
    {
        private static byte[] key = { 13, 96, 20, 121, 253, 198, 144, 142, 10, 98, 92, 55, 156, 223, 123, 11 };
        private static byte[] iv = { 1, 9, 250, 128, 100, 11, 77, 79 }; 

        /// <summary>
        /// encrypts a string and returns the encrypted data as base64 string.
        /// </summary>
        /// <param name="input">plain-text string to encrypt</param>
        /// <returns>base64 encrypted string</returns>
        public static string encrypt(string input)
        {
            byte[] bytes = encrypt(System.Text.Encoding.Default.GetBytes(input));
            return System.Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// decrypts a base64 string of encoded data.
        /// </summary>
        /// <param name="input">base64 string of encoded data</param>
        /// <returns>plaintext decrypted string</returns>
        public static string decrypt(string input)
        {           
            byte[] bytes = System.Convert.FromBase64String(input);
            return System.Text.Encoding.Default.GetString(decrypt(bytes));
        }

        static byte[] encrypt(byte[] input)
        {
            TripleDES alg = TripleDES.Create();
            alg.Padding = PaddingMode.PKCS7;
            alg.Key = key;
            alg.IV = iv;
                        
            ICryptoTransform crypto = alg.CreateEncryptor();
            
            MemoryStream output = new MemoryStream();
            CryptoStream cs = new CryptoStream(output, crypto, CryptoStreamMode.Write);
            
            cs.Write(input, 0, input.Length);

            cs.Close();

            output.Close();

            byte[] outputBytes = output.ToArray();

            alg.Clear();

            return outputBytes;
        }

        static byte[] decrypt(byte[] input)
        {
            TripleDES alg = TripleDES.Create();
            alg.Padding = PaddingMode.PKCS7;
            alg.Key = key;
            alg.IV = iv;

            ICryptoTransform crypto = alg.CreateDecryptor();
            
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, crypto, CryptoStreamMode.Write);
            cs.Write(input, 0, input.Length);
            cs.Close();            
            ms.Close();
            
            byte[] outputBytes = ms.ToArray();

            alg.Clear();

            return outputBytes;

        }
    }
}
